#define LOG_TAG "FACE_DETECT_CPP"
#include "face_detect.h"
#include "tools.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>

#define FACE_SIZE 100

// Function to detect and draw any faces that is present in an image
bool face_detect( IplImage* srcImg, std::vector<CvRect> *vectFaces, CvHaarClassifierCascade* cascade, bool detect_only)
{

    // Create memory for calculations
    static CvMemStorage* storage = 0;

    // Create two points to represent the face locations
    CvPoint pt1, pt2;
    int i;

    if( !cascade )
    {
        MY_LOG("%s: faceCascade is NULL", __FILE__);
        return false;
    }

    // Allocate the memory storage
    storage = cvCreateMemStorage(0);

    // Clear the memory storage which was used before
    cvClearMemStorage( storage );

    int max_width = 0;
    // Find whether the cascade is loaded, to find the biggest face. If yes, then:
    if( cascade )
    {

        // There can be more than one face in an image. So create a growable sequence of faces.
        // Detect the objects and store them in the sequence

        DURATION_START;
        CvSeq* faces = cvHaarDetectObjects( srcImg, cascade, storage,
                1.1, 2, CV_HAAR_DO_CANNY_PRUNING
                , cvSize(20, 20) 
                );
        DURATION_STOP("cvHaarDetectObjects()");

        // Loop the number of faces found.
        for( i = 0, max_width=0; i < faces->total; i++ )
        {
            // Create a new rectangle for the face
            CvRect* r = (CvRect*)cvGetSeqElem( faces, i );

            if(vectFaces != NULL) {
                vectFaces -> push_back(*r);
            }

            MY_LOG("%s: found face <%d,%d> with %dx%d\n", __func__, r->x, r->y, r->width, r->height);

            if(!detect_only) {
                // Draw the rectangle in the input image
                cvRectangle( srcImg, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
            }

            if(max_width < r->width) {

                pt1.x = r->x;
                pt2.x = (r->x + r->width);
                pt1.y = r->y;
                pt2.y = (r->y + r->height);

                max_width = r->width;

            }
        }

        if(max_width <= 4) {
            return false;
        }

        //printf("%s: (%d,%d), (%d,%d) -> (%d * %d)\n", __func__, pt1.x, pt1.y, pt2.x, pt2.y, (pt2.x - pt1.x) , (pt2.y - pt1.y));

        //cvSetImageROI(srcImg, cvRect(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y));
        //// __android_log_print(ANDROID_LOG_DEBUG, "run to here ", "func:%s, line:%d", __func__,__LINE__);
        //// printf("%s: srcImg ROI: (%d * %d)\n",__func__, cvGetImageROI(srcImg).width, cvGetImageROI(srcImg).height );
        //IplImage *tmpImg2 = cvCreateImage( cvSize(cvGetImageROI(srcImg).width, cvGetImageROI(srcImg).height), IPL_DEPTH_8U, 1);
        //IplImage *tmpImg = srcImg;
        ////color depth
        //if(srcImg->nChannels != 1)  {
        //    cvCvtColor(srcImg, tmpImg2, CV_BGR2GRAY);
        //    tmpImg = tmpImg2;
        //}

        ////resize
        //*dstImg = cvCreateImage(cvSize(FACE_SIZE, FACE_SIZE), IPL_DEPTH_8U, 1);
        //cvResize(tmpImg, *dstImg, CV_INTER_CUBIC);

        ////__android_log_print(ANDROID_LOG_DEBUG, "run to here ", "func:%s, line:%d", __func__,__LINE__);
        //cvResetImageROI(srcImg);

        //cvReleaseImage(&tmpImg2);
        ////__android_log_print(ANDROID_LOG_DEBUG, "run to here ", "func:%s, line:%d", __func__,__LINE__);
        
        return true;
    }

    return false;
}
